#include "StdAfx.h"
#include "ActionObject.h"
#include "PlayersManager.h"
#include "RenderingManager.h"
#include "RenderableObject.h"
#include "GraphicsController.h"
#include "IMovable.h"
#include "BoundingVolume.h"
#include <d3dx9.h>
#include <vector>


///////////////////////////////////////////////////////////////////////////////

ActionObject::ActionObject(IPlayersManager& playersManager,
                           IRenderingManager& renderingManager,
                           CRenderableObject* laserBeam,
                           CRenderableObject* actionFigure)
      : m_playersManager(playersManager),
      m_renderingManager(renderingManager),
      m_laserBeam(laserBeam),
      m_actionFigure(actionFigure),
      m_beamVisibilityTime(0),
      m_laserPower(1.0f),
      m_energyLevel(1.0f),
      m_nextGate(1),
      m_numGatesScored(0),
      m_timeUntilNextShot(0),
      m_shootingInterval(3)
{
   m_renderingManager.startRendering(*m_actionFigure);
}

///////////////////////////////////////////////////////////////////////////////

ActionObject::~ActionObject()
{
   m_renderingManager.stopRendering(*m_actionFigure);
   m_renderingManager.stopRendering(*m_laserBeam);

   delete m_laserBeam;
   m_laserBeam = NULL;

   delete m_actionFigure;
   m_actionFigure = NULL;
}

///////////////////////////////////////////////////////////////////////////////

void ActionObject::shoot()
{
   if (m_timeUntilNextShot > 0) return;

   if (m_beamVisibilityTime == 0)
   {
      updateBeamCoordinates();

      Ray shootingRay(m_laserBeam->getPosition(), m_laserBeam->getLookVec());

      std::vector<ActionObject*> hitObjects = m_playersManager.queryForObjects(shootingRay);
      for (UINT i = 0; i < hitObjects.size(); ++i)
      {
         if(this == hitObjects[i]) continue; // we're obviously not affected by our weapon :D

         hitObjects[i]->drainEnergy(m_laserPower);
      }

      m_renderingManager.startRendering(*m_laserBeam);
      m_beamVisibilityTime = 0.1f;

      m_timeUntilNextShot = m_shootingInterval;
   }
}

///////////////////////////////////////////////////////////////////////////////

void ActionObject::update(float timeElapsed)
{
   m_timeUntilNextShot -= timeElapsed;
   if (m_timeUntilNextShot < 0) m_timeUntilNextShot = 0;

   // laser rendering...
   if (m_beamVisibilityTime > 0) 
   { 
      m_beamVisibilityTime -= timeElapsed;
      updateBeamCoordinates();
   
      if (m_beamVisibilityTime <= 0) 
      {
         m_beamVisibilityTime = 0;
         m_renderingManager.stopRendering(*m_laserBeam);
      }
   }
}

///////////////////////////////////////////////////////////////////////////////

void ActionObject::drainEnergy(float amount)
{
   m_energyLevel -= amount;
   if (m_energyLevel < 0) m_energyLevel = 0;

   // avatar rendering control
   if (m_energyLevel == 0)
   {
      m_playersManager.removePlayer(this);
   }
}

///////////////////////////////////////////////////////////////////////////////

void ActionObject::updateBeamCoordinates()
{
   m_laserBeam->setRightVec(m_actionFigure->getRightVec());
   m_laserBeam->setUpVec(m_actionFigure->getUpVec());
   m_laserBeam->setLookVec(m_actionFigure->getLookVec());

   D3DXVECTOR3 laserOrigin = m_actionFigure->getPosition() - m_laserBeam->getPosition();
   laserOrigin.y += 2;
   m_laserBeam->move(laserOrigin);
}

///////////////////////////////////////////////////////////////////////////////

IMovable& ActionObject::getMovable() 
{
   return *m_actionFigure;
}

///////////////////////////////////////////////////////////////////////////////
